<?php
class CriarBackend {

    /**
     * Cria o arquivo index.php que realiza a chamada ao controller
     *
     * @param Tabela $objTabela
     * @return String
     */
    public static function criarIndex($objTabela) {
        $t = '    ';
        /* Primeiro caracter em maiusculo, como manda a convencao. */
        $tabela = Util::nomeDbToClasse($objTabela->getNomeTabela());

        /* Iniciando a criacao do conteudo do arquivo */
        $conteudo = '<?php' . "\n";
        $conteudo .= "$t" . 'include \'imports.inc.php\';' . "\n";
        $conteudo .= "$t" . '$_POST[\'t\'] = Util::getRequestVal($_GET, \'t\');' . "\n";
        $conteudo .= "$t" . '$controller = new ' . $tabela . 'Controller();' . "\n";
        $conteudo .= "$t" . '$controller->execute($_POST);' . "\n";
        $conteudo .= "?>\n";
        
        return $conteudo;
    }
    
    /**
     * Cria o arquivo imports.php que realiza os includes
     *
     * @param Tabela $objTabela
     * @return String
     */
    public static function criarImports($objTabela) {
        $t = '    ';
        /* Primeiro caracter em maiusculo, como manda a convencao. */
        $tabela = Util::nomeDbToClasse($objTabela->getNomeTabela());
        $pasta = Util::nomeDbToAtributo($objTabela->getNomeTabela());

        /* Iniciando a criacao do conteudo do arquivo */
        $conteudo = '<?php' . "\n";
        $conteudo .= "$t" . '//Configurações gerais' . "\n";
        $conteudo .= "$t" . 'require_once \'../../config/importsObrigatorios.inc.php\';' . "\n";

        $conteudo .= "\n$t" . '//Classes Entity' . "\n";
        $conteudo .= "$t" . 'require_once \'../../classes/entity/' . $pasta . '/' . $tabela . '.class.php\';' . "\n";
        $conteudo .= "$t" . 'require_once \'../../classes/entity/' . $pasta . '/' . $tabela . 'Dao.class.php\';' . "\n";
        $conteudo .= "$t" . 'require_once \'../../classes/entity/' . $pasta . '/' . $tabela . 'Helper.class.php\';' . "\n";

        $conteudo .= "\n$t" . '//Classes MVC' . "\n";
        $conteudo .= "$t" . 'require_once \'classes/' . $tabela . 'Controller.class.php\';' . "\n";
        $conteudo .= "$t" . 'require_once \'classes/' . $tabela . 'Model.class.php\';' . "\n";
        $conteudo .= "$t" . 'require_once \'classes/' . $tabela . 'ServiceDao.class.php\';' . "\n";
        
        $conteudo .= "?>\n";
        
        return $conteudo;
    }
    
    /**
     * Cria o arquivo .htaccess que realiza os includes
     *
     * @param Tabela $objTabela
     * @return String
     * @return string
     */
    public static function criarHtaccess($objTabela) {
        $conteudo = 'RewriteEngine On
Options All -Indexes
DirectoryIndex index.php
RewriteRule ^([0-9a-zA-Z]{1,20})$ index.php?t=$1 [L]';
        
        return $conteudo;
    }
    
    /**
     * Cria o arquivo [tabela]Controller.php que realiza as chamadas ao service.
     * @param Tabela $objTabela
     * @return String
     */
    public static function criarController($objTabela) {
        $t = '    ';
        /* Primeiro caracter em maiusculo, como manda a convencao. */
        $nomeClasse = Util::nomeDbToClasse($objTabela->getNomeTabela());
        $nomeAtributo = Util::nomeDbToAtributo($objTabela->getNomeTabela());
        
        /* Iniciando a criacao do conteudo do arquivo */
        $conteudo  = '<?php' . "\n";
        $conteudo .= "$t" . 'require_once ROOT . \'server/classes/arquitetura/controller/AbstractController.class.php\';' . "\n";
        $conteudo .= "\n$t" . '/**
     * Esta classe efetua todas as chamadas para execução do service.
     * @author Tiago <tiago.professor@gmail.com>
     */';
        $conteudo .= "\n$t" . 'class ' . $nomeClasse . "Controller extends AbstractController {\n";
        
        //Abrindo o metodo specificExecute
        $conteudo .= "\n$t" . '    /**
         * Executa o processamento principal
         * @author Tiago <tiago.professor@gmail.com>
         * @param type $objRequest
         */
        public function specificExecute($objRequest) {
            if($this->log->isDebugEnabled()) {
                $this->log->logDebug(\'Executando o método specificExecute()\');
            }';
        
        //Fechando o metodo specificExecute
        $conteudo .= "\n$t$t" . '    //Executando a chamada ao service.
            $this->getService()->execute();
        }' . "\n";
        
        //Metodo populandoAtributos
        $conteudo .= "\n$t" . '    /**
         * Popula os atributos desta classe
         * @author Tiago <tiago.professor@gmail.com>
         * @param type $objRequest
         */
        public function populandoAtributos($objRequest) {
            if($this->log->isDebugEnabled()) {
                $this->log->logDebug(\'Executando o método populandoAtributos()\');
            }
            $' . $nomeAtributo . ' = ' . $nomeClasse . 'Helper::getObjFromRequest($objRequest);

            $model = new ' . $nomeClasse . 'Model();
            $model->setResult(new GenericResult());
            $model->set' . $nomeClasse . '($' . $nomeAtributo . ');
            $model->setAction(Util::getRequestVal($objRequest, \'t\'));//Ação que será executada.

            $service = new ' . $nomeClasse . 'ServiceDao();
            $service->setModel($model);

            $this->setModel($model);
            $this->setService($service);
        }' . "\n";
        
        $conteudo .= "\n$t" . '    /**
         * Efetua a validação dos dados recebidos pelo formulario
         * que estao no model.
         */
        public function isModelValido() {
            if($this->log->isDebugEnabled()) {
                $this->log->logDebug(\'Executando o método isModelValido()\');
            }
            return ' . $nomeClasse . 'Helper::validarModel($this->getModel());
        }' . "\n";
        
        
        $conteudo .= "$t}\n?>\n";
        
        return $conteudo;
    }
    
    /**
     * Cria o arquivo [tabela]Model.php que realiza as chamadas ao service.
     * @param Tabela $objTabela
     * @return String
     */
    public static function criarModel($objTabela) {
        $t = '    ';
        /* Primeiro caracter em maiusculo, como manda a convencao. */
        $nomeClasse = Util::nomeDbToClasse($objTabela->getNomeTabela());
        $nomeAtributo = Util::nomeDbToAtributo($objTabela->getNomeTabela());
        
        /* Iniciando a criacao do conteudo do arquivo */
        $conteudo  = '<?php' . "\n";
        $conteudo .= "$t" . 'require_once ROOT . \'server/classes/arquitetura/model/AbstractModel.class.php\';' . "\n";
        $conteudo .= "\n" . '    /**
     * Esta classe representa as informações da tela.
     * @author Tiago <tiago.professor@gmail.com>
     */';
        $conteudo .= "\n$t" . 'class ' . $nomeClasse . "Model extends AbstractModel {\n";
        
        //Conteudo da classe
        $conteudo .= "$t" . '    //Entity Object
        private $' . $nomeAtributo . ';

        /**
         * Método set
         * @author Tiago <tiago.professor@gmail.com>
         * @param $' . $nomeAtributo . '
         */
        public function set' . $nomeClasse . '($' . $nomeAtributo . ') {
            $this->' . $nomeAtributo . ' = $' . $nomeAtributo . ';
        }

        /**
         * Método get
         * @author Tiago <tiago.professor@gmail.com>
         * @return $' . $nomeAtributo . '
         */
        public function get' . $nomeClasse . '() {
            return $this->' . $nomeAtributo . ';
        }' . "\n";
        
        
        $conteudo .= "$t}\n?>\n";
        
        return $conteudo;
    }
    
    /**
     * Cria o arquivo [tabela]Controller.php que realiza as chamadas ao service.
     * @param Tabela $objTabela
     * @return String
     */
    public static function criarServiceDao($objTabela) {
        $t = '    ';
        /* Primeiro caracter em maiusculo, como manda a convencao. */
        $nomeClasse = Util::nomeDbToClasse($objTabela->getNomeTabela());
        $nomeAtributo = Util::nomeDbToAtributo($objTabela->getNomeTabela());
        
        /* Iniciando a criacao do conteudo do arquivo */
        $conteudo  = '<?php' . "\n";
        $conteudo .= "$t" . 'require_once ROOT . \'server/classes/arquitetura/service/AbstractService.class.php\';' . "\n";
        $conteudo .= "\n" . '    /**
     * Esta classe executa as chamadas DAO.
     * @author Tiago <tiago.professor@gmail.com>
     */';
        $conteudo .= "\n$t" . 'class ' . $nomeClasse . "ServiceDao extends AbstractService {\n";
        
        //Metodo executarSalvar
        $conteudo .= "\n$t" . '    /**
         * Executa as chamadas de insert ou update no banco de dados.
         * @author Tiago <tiago.professor@gmail.com>
         */
        public function executarSalvar() {
            $registroJaExiste = isset($this->getModel()->get' . $nomeClasse . '()->getId());
            $dao = new ' . $nomeClasse . 'Dao($this->getModel()->get' . $nomeClasse . '());

            $sqlToExec = $registroJaExiste ? $dao->getUpdateSQL() : $dao->getInsertSQL();
            $sqlResult = $this->conn->executeQuery($sqlToExec);

            $numRows = 0; //Zero
            if($sqlResult) {
                //Tem que retornar só uma linha.
                $numRows = $this->conn->getNumRows($sqlResult);
            }

            if ($numRows == self::ONE_ROW) {
                $row = $this->conn->fetchAssoc($sqlResult);
                $this->getModel()->set' . $nomeClasse . '(' . $nomeClasse . 'Helper::getObjFromDB($row));
                if (!($registroJaExiste)) {
                    $this->getModel()->get' . $nomeClasse . '()->setId($this->conn->getAutoId());
                }
            } else {
                //Erro
                $this->getModel()->setResult(ResultFactory::newResultFalha(\'Erro\', \'Erro inserindo/atualizando ' . $nomeAtributo . '.\'));
            }
        }' . "\n";
        
        //Metodo executarSalvarComo
        $conteudo .= "\n$t" . '    /**
         * Executa a chamada para persistir o novo registro no banco de dados.
         * @author Tiago <tiago.professor@gmail.com>
         */
        public function executarSalvarComo() {
            $dao = new ' . $nomeClasse . 'Dao($this->getModel()->get' . $nomeClasse . '());

            $sqlToExec = $dao->getInsertSQL();
            $sqlResult = $this->conn->executeQuery($sqlToExec);

            $numRows = 0; //Zero
            if($sqlResult) {
                //Tem que retornar só uma linha.
                $numRows = $this->conn->getNumRows($sqlResult);
            }
        
            if ($numRows == self::ONE_ROW) {
                $row = $this->conn->fetchAssoc($sqlResult);
                $this->getModel()->set' . $nomeClasse . '(' . $nomeClasse . 'Helper::getObjFromDB($row));
                $this->getModel()->get' . $nomeClasse . '()->setId($this->conn->getAutoId());
            } else {
                //Erro
                $this->getModel()->setResult(ResultFactory::newResultFalha(\'Erro\', \'Erro inserindo/atualizando ' . $nomeAtributo . '.\'));
            }
        }' . "\n";
        
        //Metodo executarSalvarComo
        $conteudo .= "\n$t" . '    /**
         * Instrução SQL para ser executada.
         * @author Tiago <tiago.professor@gmail.com>
         * @return string
         */
        public function getSqlConsulta() {
            $dao = new ' . $nomeClasse . 'Dao($this->getModel()->get' . $nomeClasse . '());
            return $dao->getByEntityFindNoNullSQL();
        }' . "\n";
        
        $conteudo .= "$t}\n?>\n";
        
        return $conteudo;
    }
}

?>